package m3f.factorization;

import org.jblas.DoubleMatrix;

import m3f.data.MultimodalDataProvider;

public class ParallelOnlineJointFactorization extends OnlineJointFactorization{
		
	public ParallelOnlineJointFactorization(MultimodalDataProvider set){
		super(set);
	}
	
	@Override
	public void run(int latentFactors, double lambda, double gamma0, double alpha, double beta, double omega, int epochs, int minibatch, boolean skipError){
		this.factors = latentFactors;
		this.omega = omega;
		trainingData.setMinibatchSize(minibatch);
		lambdaI = DoubleMatrix.eye(factors).muli(lambda);
		initialize(factors, trainingData.visualFeatures(), trainingData.textFeatures());
		if(!skipError){
			computeError();
			System.out.println("Initial error: visualError=" + visualError + " textError=" + textError);
		}
		ConcurrentOnlineLearner col = new ConcurrentOnlineLearner(trainingData, latentFactors, gamma0, lambda, alpha, beta, omega);
		for(int i = 0; i < epochs; i++){
			// Epochs should be handled by the concurrent learner as well
			trainingData.reset(true);
			System.out.println("Training epoch " + i);
			Thread thread = new Thread(col);
			thread.start();
			try{
				thread.join();
			}catch(InterruptedException ie){
				ie.printStackTrace();
			}
			P = col.getFinalP();
			Q = col.getFinalQ();
			System.out.println("Epoch " + i + " done");
			if(!skipError){
				computeError();
				System.out.println("Epoch " + i + ": visualError=" + visualError + " textError=" + textError);
			}
		}
	}
}